package com.michaelwolf.mytool.wcfcompmanger.ui;

import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;

import javax.swing.JTree;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;

import org.w3c.dom.Node;

import com.michaelwolf.mytool.wcfcompmanger.wcfanalyzer.NodeHandler;
import com.michaelwolf.mytool.wcfcompmanger.wcfanalyzer.WCFLoader.TraverseCacheData;

public class NodeTreeDiplayService {
	
	public static void displayNodeOnTree(TraverseCacheData traverseCacheData, JTree relateTree, String keyword) {
		Set<Node> nodeSet = traverseCacheData.getFoundNode();
		Set<Node> compNodeSet = new HashSet<Node>();
		for(Node node : nodeSet){
			if(isStringPropertyNode(node)){
				keyword = node.getNodeValue();
			}
			
			Node compNode = NodeHandler.getOwnerCompNode(node);
			if(compNode != null ){
				compNodeSet.add(compNode);
			}
		}
		DefaultMutableTreeNode rootNode = new DefaultMutableTreeNode();
		rootNode.setUserObject("Search Result");
		DefaultTreeModel dm = new DefaultTreeModel(rootNode);
		relateTree.setModel(dm);
		
		Map<String, DefaultMutableTreeNode> moduleTreeNodeMap = new HashMap<>();
		
		for(Node compNode : compNodeSet){
			
			String moduleDisplayName = compNode.getOwnerDocument().getFirstChild().getAttributes().getNamedItem("display-name").getNodeValue();
			DefaultMutableTreeNode moduleNode;
			if(moduleTreeNodeMap.containsKey(moduleDisplayName)){
				moduleNode = moduleTreeNodeMap.get(moduleDisplayName);
				
			}else{
				moduleNode = new DefaultMutableTreeNode();
				moduleNode.setUserObject(moduleDisplayName);
				moduleTreeNodeMap.put(moduleDisplayName, moduleNode);
				rootNode.add(moduleNode);
				
				
			}
			DefaultMutableTreeNode displayNode = new DefaultMutableTreeNode();
			String moduleName = traverseCacheData.getModuleDisplayNameMap().get(moduleDisplayName);
			displayNode.setUserObject(new WCFNodeObject(compNode, keyword, moduleName));
			
			moduleNode.add(displayNode);
			
			List<Node> nodeRecordSet = new ArrayList<>();
			addDependentNodes(displayNode, traverseCacheData,nodeRecordSet);
		}
		
		//display non-groovy script file search result
		
		Set<File> nonGroovyFileSet = traverseCacheData.getFoundNonGroovyFileSet();
		if(nonGroovyFileSet == null || nonGroovyFileSet.isEmpty()){
			return;
		}
		
		DefaultMutableTreeNode nonGroovyScriptTitleNode = new DefaultMutableTreeNode();
		nonGroovyScriptTitleNode.setUserObject("Non-Groovy Script File");
		rootNode.add(nonGroovyScriptTitleNode);
		
		for(File nonGroovyFile : nonGroovyFileSet){
			DefaultMutableTreeNode nonGroovyScriptFileNode = new DefaultMutableTreeNode();
			nonGroovyScriptFileNode.setUserObject(new FileNodeObject(nonGroovyFile, keyword));
			nonGroovyScriptTitleNode.add(nonGroovyScriptFileNode);
		}
		
	}
	
	private static final Pattern STRING_PROPERTY_PATTERN = Pattern.compile("system:storage\\w.*\\.plain\\.\\d.*");
	private static boolean isStringPropertyNode(Node node) {
		String nodeValue = node.getNodeValue();
		if(nodeValue == null){
			return false;
		}
		
		return STRING_PROPERTY_PATTERN.matcher(nodeValue).find();
	}

	private static void addDependentNodes(DefaultMutableTreeNode dependentDisplayNode,
			TraverseCacheData traverseCacheData, List<Node> nodeRecordSet) {
		WCFNodeObject userNodeObject = (WCFNodeObject) dependentDisplayNode.getUserObject();
		Node node = userNodeObject.getNode();
		Map<Node, Set<Node>>  dependencyMap = traverseCacheData.getDependencyMap();
		Map<String, String> moduleDisplayNameMap = traverseCacheData.getModuleDisplayNameMap();
		
		
		if(dependencyMap.get(node) != null){
			for(Node dependencyNode : dependencyMap.get(node)){
				if(dependencyNode == node){
					continue;
				}
				String moduleDisplayName = dependencyNode.getOwnerDocument().getFirstChild().getAttributes().getNamedItem("display-name").getNodeValue();
				DefaultMutableTreeNode displayNode = new DefaultMutableTreeNode();
				displayNode.setUserObject(new WCFNodeObject(dependencyNode, node.getAttributes().getNamedItem("id").getNodeValue(), moduleDisplayNameMap.get(moduleDisplayName)));
				
				if(nodeRecordSet.contains(dependencyNode)){
					continue;
				}else{
					nodeRecordSet.add(dependencyNode);
					dependentDisplayNode.add(displayNode);
					addDependentNodes(displayNode, traverseCacheData, nodeRecordSet);
				}
				
			}
		}
		
		Map<Node,Set<Node>> scriptReferMap = traverseCacheData.getScriptReferMap();
		if(scriptReferMap.get(node)!=null){
			for(Node scriptReferNode : scriptReferMap.get(node)){
				if(scriptReferNode == node){
					continue;
				}
				
				if(scriptReferNode == null){
					continue;
				}
				
				DefaultMutableTreeNode displayNode = new DefaultMutableTreeNode();
				String moduleDisplayName = scriptReferNode.getOwnerDocument().getFirstChild().getAttributes().getNamedItem("display-name").getNodeValue();
				displayNode.setUserObject(new WCFNodeObject(scriptReferNode, node.getAttributes().getNamedItem("id").getNodeValue(), moduleDisplayNameMap.get(moduleDisplayName)));
				if(nodeRecordSet.contains(scriptReferNode)){
					continue;
				}else{
					nodeRecordSet.add(scriptReferNode);
					dependentDisplayNode.add(displayNode);
					addDependentNodes(displayNode, traverseCacheData, nodeRecordSet);
				}
			}
		}
		
		
		
		
	}

	

}
